package com.business.dynamic.service.impl;


import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.business.common.config.FileUploadConfig;
import com.business.common.constant.MessageConstant;
import com.business.common.enums.BusinessExceptionEnum;
import com.business.common.enums.ErrorEnum;
import com.business.common.exception.BusinessException;
import com.business.common.exception.CustomException;
import com.business.common.utils.FileUploadUtil;
import com.business.common.utils.PageUtils;
import com.business.common.utils.StrKit;
import com.business.dynamic.dto.DynamicParams;
import com.business.dynamic.entity.*;
import com.business.dynamic.entity.vo.DynamicVo;
import com.business.dynamic.mapper.*;
import com.business.dynamic.rabbitMq.RabbitMqSender;
import com.business.dynamic.service.DynamicDefaultAttributeService;
import com.business.dynamic.service.DynamicService;
import com.business.redis.ExpiresTimeEnum;
import com.business.redis.constant.RedisKeyConstant;
import com.business.redis.utils.RedisUtil;
import com.business.user.entity.MessageDto;
import com.business.user.entity.UserDetailsDto;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Pattern;


/**
 * 动态表:业务接口实现类
 *
 * @author chenjiehong
 * @date 2019-11-29 15:15:38
 * @since 1.0
 */
@Service
public class DynamicServiceImpl implements DynamicService {

    @Autowired
    private DynamicMapper dynamicMapper;

    @Autowired
    private DynamicImagesMapper dynamicImagesMapper;

    @Autowired
    private DynamicAttributeMapper dynamicAttributeMapper;

    @Autowired
    private DynamicDefaultAttributeService dynamicDefaultAttributeService;

    @Autowired
    private DynamicMessageMapper dynamicMessageMapper;

    @Autowired
    private DynamicLikeMapper dynamicLikeMapper;

    @Autowired
    private DynamicCommentMapper dynamicCommentMapper;

    @Autowired
    private PlatformTransactionManager transactionManager;

    private ThreadPoolExecutor pool = new ThreadPoolExecutor(9, 30, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>());

    private Logger logger = LoggerFactory.getLogger(DynamicServiceImpl.class);

    @Autowired
    private RabbitMqSender rabbitMqSender;

    @Autowired
    private UserServiceImpl userService;

    @Autowired
    private FileUploadUtil fileUploadUtil;


    protected DynamicVo asynAdd(DynamicVo dynamicVo) {
        dynamicVo.setState(1);
        dynamicVo.setCreateTime(new Date());
        dynamicVo.setShareQuantity(0);
        dynamicVo.setLikeQuantity(0);
        dynamicVo.setCommentQuantity(0);
        //解析富文本 获取图片
        Document document = Jsoup.parse(dynamicVo.getContent());
        Elements elements = document.select("img[src]");
        if (elements.size() > 0) {
            dynamicVo.setImageList(new ArrayList<>(elements.size()));
        }
        elements.forEach(element -> {
            String src = element.attr("src");
            int index = src.indexOf(FileUploadConfig.FILE_DIRECTORY);
            if (index > -1) {
                //插入图片
                String url = src.substring(index, src.indexOf("?"));
                dynamicVo.getImageList().add(url);
                element.attr("src", url);//替换src
                //删除缓存中url
                String key = String.format(RedisKeyConstant.DYNAMIC_UPLOAD_IMAGES, dynamicVo.getUserId());
                RedisUtil.removeSetValue(key, src);
            }
        });
        //替换富文本
        dynamicVo.setContent(document.body().children().outerHtml());
        dynamicVo.setImagesQuantity(elements.size());
        dynamicVo.setAttributeQuantity(dynamicVo.getAttributeList().size());
        dynamicMapper.insert(dynamicVo);

        //插入图片
        if (dynamicVo.getImageList() != null && dynamicVo.getImageList().size() > 0) {
            AtomicInteger sort = new AtomicInteger();
            dynamicVo.getImageList().forEach(url -> {
                sort.getAndIncrement();
                DynamicImages dynamicImages = new DynamicImages();
                dynamicImages.setDynamicId(dynamicVo.getId());
                dynamicImages.setCreateTime(new Date());
                dynamicImages.setUrl(url);
                dynamicImages.setSort(sort.get());
                dynamicImagesMapper.insert(dynamicImages);
            });
        }

        //插入属性
        if (dynamicVo.getAttributeList() != null && dynamicVo.getAttributeList().size() > 0) {
            dynamicVo.getAttributeList().forEach(a -> {
                if (StrKit.isBlank(a.getValue())) {
                    return;
                }
                a.setDynamicId(dynamicVo.getId());
                dynamicAttributeMapper.insert(a);
            });
        }

        //插入标签到缓存中
        if (StrKit.isNotEmpty(dynamicVo.getTags())) {
            String[] tags = dynamicVo.getTags().split(",");
            String key1 = String.format(RedisKeyConstant.USER_DETAILS_HOT_TAG_LIST, dynamicVo.getParentCategoryCode());

            for (String tag : tags) {
                RedisUtil.incrementScore(key1, tag, 1);
            }
        }
        return dynamicVo;
    }

    @Override
    public DynamicVo add(DynamicVo dynamicVo) {
        //判断标签长度
        if (StrKit.isNotEmpty(dynamicVo.getTags())) {
            String[] tags = dynamicVo.getTags().split(",");
            //判断标签长度
            if (tags.length > 5) {
                throw new BusinessException(BusinessExceptionEnum.DYNAMIC_TAG_SIZE_ERROR);
            }
            for (String tag : tags) {
                if (tag != null && tag.length() > 10) {
                    throw new BusinessException(BusinessExceptionEnum.DYNAMIC_TAG_LENGTH_ERROR);
                }
            }
        }
        //提交的属性
        List<DynamicAttribute> attributeList = dynamicVo.getAttributeList();
        if (attributeList != null) {
            //判断属性名称是否为空
            if (attributeList.size() > 0) {
                attributeList.forEach(a -> {
                    if (StrKit.isBlank(a.getName())) {
                        throw new BusinessException(BusinessExceptionEnum.DYNAMIC_ATTRIBUTE_NAME_NULL);
                    }
                });
            }
            //判断属性长度
            if (attributeList.size() > 30) {
                throw new BusinessException(BusinessExceptionEnum.DYNAMIC_ATTRIBUTE_SIZE_ERROR);
            }
        }

        //判断属性
        List<DynamicDefaultAttribute> defaultAttributeList = dynamicDefaultAttributeService.queryList(dynamicVo.getType(), dynamicVo.getParentCategoryCode(), dynamicVo.getSubCategoryCode());
        if (defaultAttributeList.size() > 0) {

            defaultAttributeList.forEach(da -> {
                //如果是必须的或者正则表达式存在就校验属性值
                if (da.getIsRequired() == 1 || StrKit.isNotEmpty(da.getRegularExpression())) {
                    if (da.getIsRequired() == 1 && attributeList == null) {
                        throw new BusinessException(9, "属性" + da.getName() + "是必须的");
                    }
                    AtomicBoolean existFlag = new AtomicBoolean(false);
                    AtomicReference<String> value = new AtomicReference<>();
                    attributeList.forEach(a -> {
                        if (a.getAttributeId() == da.getId() && StrKit.isNotEmpty(a.getValue())) {
                            existFlag.set(true);
                            value.set(a.getValue());
                            return;
                        }
                    });
                    //是必须的
                    if (da.getIsRequired() == 1 && !existFlag.get()) {
                        throw new BusinessException(9, "属性" + da.getName() + "不能为空");
                    }
                    //存在正则表达式
                    if (StrKit.isNotEmpty(da.getRegularExpression()) && existFlag.get()) {
                        //格式不正确
                        if (Pattern.matches(da.getRegularExpression(), value.get())) {
                            throw new BusinessException(10, da.getErrorMessage());
                        }
                    }
                }
            });
        }
        //异步插入数据库
        pool.execute(() -> {
            //异步情况下 @Transaction 没有效果
            DefaultTransactionDefinition def = new DefaultTransactionDefinition();
            def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔离级别，开启新事务，这样会比较安全些。
            TransactionStatus status = transactionManager.getTransaction(def); // 获得事务状态
            boolean addQuantityFlag = false;
            try {
                asynAdd(dynamicVo);
                logger.info("动态添加成功:" + dynamicVo);
                //发送统计用户数量消息
                rabbitMqSender.sendAddUserDataQuantity(dynamicVo.getUserId(), "dynamic" + dynamicVo.getType(), 1);
                addQuantityFlag = true;
                //提交事务
                transactionManager.commit(status);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                if (addQuantityFlag) {
                    //发送统计用户数量消息
                    rabbitMqSender.sendAddUserDataQuantity(dynamicVo.getUserId(), "dynamic" + dynamicVo.getType(), -1);
                }
                //发送消息 提醒用户
                MessageDto messageDto = new MessageDto();
                messageDto.setUserId(dynamicVo.getUserId());
                messageDto.setType(0);
                messageDto.setContent(String.format(MessageConstant.DYNAMIC_ADD_FAIL, dynamicVo.getTitle()));
                rabbitMqSender.addMessage(messageDto);
                //回滚 事务  这样做一个线程出问题 只能回滚出问题的线程
                transactionManager.rollback(status);
            }
        });
        return dynamicVo;
    }

    @Override
    @Transactional(readOnly = true)
    public DynamicVo query(Integer id,Integer userId) {
        DynamicVo dynamicVo = dynamicMapper.queryOneById(id,userId);
        List<DynamicVo> list = new ArrayList<>();
        list.add(dynamicVo);
        setDetails(list, true);
        return dynamicVo;
    }


    @Override
    @Transactional
    public Integer updateState(Integer dynamicId, Integer state, Integer userDtoId) {
        Integer dynamicUserId = dynamicMapper.getDynamicUserId(dynamicId);
        if (dynamicUserId == null) {
            throw new BusinessException(BusinessExceptionEnum.DYNAMIC_NOT_EXIST);
        }
        if (dynamicUserId != userDtoId) {
            throw new CustomException(ErrorEnum.NO_PERMISSION);
        }
        Dynamic dynamic = new Dynamic();
        dynamic.setId(dynamicId);
        dynamic.setState(state);

        return dynamicMapper.updateById(dynamic);

    }

    @Override
    public Integer delete(Integer id, Integer userDtoId) {
        Dynamic dynamic = dynamicMapper.getTypeAndUserId(id);
        if (dynamic == null) {
            throw new BusinessException(BusinessExceptionEnum.DYNAMIC_NOT_EXIST);
        }
        if (dynamic.getUserId() != userDtoId) {
            throw new CustomException(ErrorEnum.NO_PERMISSION);
        }
        //异步删除
        pool.execute(() -> {
            //异步情况下 @Transaction 没有效果
            DefaultTransactionDefinition def = new DefaultTransactionDefinition();
            def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔离级别，开启新事务，这样会比较安全些。
            TransactionStatus status = transactionManager.getTransaction(def); // 获得事务状态

            boolean addQuantityFlag = false;
            //记录要删除图片
            try {
                //删除属性
                dynamicAttributeMapper.delete(new EntityWrapper<DynamicAttribute>().eq("dynamic_id", id));

                //删除点赞 和评论
                dynamicLikeMapper.delete(new EntityWrapper<DynamicLike>().eq("dynamic_id", id));
                dynamicCommentMapper.delete(new EntityWrapper<DynamicComment>().eq("dynamic_id", id));
                //删除动态消息
                dynamicMessageMapper.delete(new EntityWrapper<DynamicMessage>().eq("dynamic_id", id));
                //删除图片
                List<String> images = dynamicImagesMapper.getUrlList(id);
                dynamicImagesMapper.delete(new EntityWrapper<DynamicImages>().eq("dynamic_id", id));

                //删除动态
                Integer result = dynamicMapper.deleteById(id);
                if (result > 0) {
                    logger.info("动态删除成功:id=" + id);
                    //发送统计用户数量消息
                    rabbitMqSender.sendAddUserDataQuantity(dynamic.getUserId(), "dynamic" + dynamic.getType(), -1);
                    addQuantityFlag = true;
                }
                //提交事务
                transactionManager.commit(status);
                //删除文件中的图片
                if (images != null && images.size() > 0) {
                    fileUploadUtil.batchDelFile(images);
                }

            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                //发送消息 提醒用户
                MessageDto messageDto = new MessageDto();
                messageDto.setUserId(dynamic.getUserId());
                messageDto.setType(0);
                messageDto.setContent(String.format(MessageConstant.DYNAMIC_DELETE_FAIL, dynamic.getTitle()));
                if (addQuantityFlag) {
                    //发送统计用户数量消息
                    rabbitMqSender.sendAddUserDataQuantity(dynamic.getUserId(), "dynamic" + dynamic.getType(), 1);
                }
                //回滚 事务  这样做一个线程出问题 只能回滚出问题的线程
                transactionManager.rollback(status);
            }

        });
        return 1;
    }

    /**
     * 设置用户信息 和 属性 tag images
     *
     * @param list
     */
    private void setDetails(List<DynamicVo> list, boolean isQueryOne) {
        Set<Integer> ids = new HashSet<>();
        final CountDownLatch countDownLatch = new CountDownLatch(list.size() + 1);

        for (DynamicVo dynamicVo : list) {
            pool.execute(() -> {
                try {
                    if (dynamicVo.getAttributeQuantity() > 0) {
                        String attributeListKey = String.format(RedisKeyConstant.DYNAMIC_ATTRIBUTE_LIST, dynamicVo.getId());
                        //获取属性
                        List<DynamicAttribute> dynamicAttributeList = null;
                        if (RedisUtil.hasKey(attributeListKey)) {
                            dynamicAttributeList = RedisUtil.getArray(attributeListKey, DynamicAttribute.class);
                        } else {
                            dynamicAttributeList = dynamicAttributeMapper.selectList(new EntityWrapper<DynamicAttribute>().eq("dynamic_id", dynamicVo.getId()));
                            RedisUtil.setValue(attributeListKey, dynamicAttributeList, ExpiresTimeEnum.LEVEL_8.getExpiresTime());
                        }
                        dynamicVo.setAttributeList(dynamicAttributeList);
                    }
                    if (dynamicVo.getImagesQuantity() > 0) {
                        String imagesListKey = String.format(RedisKeyConstant.DYNAMIC_IMAGES, dynamicVo.getId());
                        //获取images
                        List<String> dynamicImagesList = null;
                        if (RedisUtil.hasKey(imagesListKey)) {
                            dynamicImagesList = RedisUtil.getArray(imagesListKey, String.class);
                        } else {
                            dynamicImagesList = dynamicImagesMapper.getUrlList(dynamicVo.getId());
                            //设置全地址
                            for (int i = 0; i < dynamicImagesList.size(); i++) {
                                String newUrl = fileUploadUtil.getUrl(dynamicImagesList.get(i));
                                dynamicImagesList.set(i, newUrl);
                            }
                            RedisUtil.setValue(imagesListKey, dynamicImagesList, ExpiresTimeEnum.LEVEL_8.getExpiresTime());
                        }
                        if (!isQueryOne) {
                            dynamicVo.setImageList(dynamicImagesList);
                        } else {
                            //替换富文本中的地址
                            for (int i = 0; i < dynamicImagesList.size(); i++) {
                                int index = dynamicImagesList.get(i).indexOf(FileUploadConfig.FILE_DIRECTORY);
                                String oldUrl = dynamicImagesList.get(i).substring(index, dynamicImagesList.get(i).indexOf("?"));
                                String content = dynamicVo.getContent().replace(oldUrl, dynamicImagesList.get(i));
                                dynamicVo.setContent(content);
                            }
                        }
                    }

                } finally {
                    countDownLatch.countDown();
                }
            });

            if (dynamicVo.getUserId() != null) {
                ids.add(dynamicVo.getUserId());
            }
        }
        pool.execute(() -> {
            try {
                //获取用户信息
                Map<Integer, UserDetailsDto> nameMap = userService.getUserNameList(ids);
                for (DynamicVo dynamicVo : list) {
                    UserDetailsDto userDto = nameMap.get(dynamicVo.getUserId());
                    if (userDto != null) {
                        dynamicVo.setUserRealName(userDto.getRealName());
                        dynamicVo.setUserHeadUrl(userDto.getHeadUrl());
                    }
                }
            } finally {
                countDownLatch.countDown();
            }
        });
        try {
            //等待所有线程执行完
            countDownLatch.await();
        } catch (InterruptedException e) {
            logger.error(e.getMessage(), e);
        }

    }

    private void setVisibility(EntityWrapper entityWrapper, Integer userId) {
        if (userId != null) {
            UserDetailsDto userDetailsDto = userService.getUserName(userId);
            //会员
            if (userDetailsDto != null && userDetailsDto.getType() != null && userDetailsDto.getType() == 1) {
                entityWrapper.in("visibility", "1, 4");
            } else {
                entityWrapper.eq("visibility", 1);
            }
        } else {
            entityWrapper.eq("visibility", 1);
        }

    }

    private void setVisibilityByFriend(EntityWrapper entityWrapper, Integer userId) {
        if (userId != null) {
            UserDetailsDto userDetailsDto = userService.getUserName(userId);
            //会员
            if (userDetailsDto != null && userDetailsDto.getType() != null && userDetailsDto.getType() == 1) {
                entityWrapper.in("visibility", "1,3,4");
            } else {
                entityWrapper.in("visibility", "1,3");
            }
        } else {
            entityWrapper.in("visibility", "1,3");
        }

    }

    @Override
    public PageUtils queryPageByUser(Page<Dynamic> page, Integer userId) {
        Set<Integer> idList = userService.getFriendList(userId);
        if (idList == null || idList.size() == 0) {
            logger.warn("用户未关注任何用户,userId=" + userId);
            PageUtils pageUtils = new PageUtils(new ArrayList<>(), page.getTotal());
            return pageUtils;
        }
        EntityWrapper<Dynamic> entityWrapper = new EntityWrapper<>();
        setVisibilityByFriend(entityWrapper, userId);
        entityWrapper.ne("d.state", 0).in("d.user_id", idList).orderBy("d.id", false);

        page.setOptimizeCount(true);
        List<DynamicVo> resultList = dynamicMapper.queryPage(page, entityWrapper,userId);
        setDetails(resultList, false);
        PageUtils pageUtils = new PageUtils(resultList, page.getTotal());
        return pageUtils;
    }


    @Override
    public PageUtils queryPageByMyself(Page<Dynamic> page, Integer userId) {
        EntityWrapper<Dynamic> entityWrapper = new EntityWrapper<>();
        setVisibilityByFriend(entityWrapper, userId);
        entityWrapper.ne("d.state", 0).eq("d.user_id",userId).orderBy("d.id", false);
        setVisibilityByFriend(entityWrapper, userId);
        page.setOptimizeCount(true);
        List<DynamicVo> resultList = dynamicMapper.queryPage(page, entityWrapper,userId);
        setDetails(resultList, false);
        PageUtils pageUtils = new PageUtils(resultList, page.getTotal());
        return pageUtils;
    }

    @Override
    public PageUtils queryPageByUserTag(Page<Dynamic> page, Integer userId) {
        List<String> tagList = userService.getTagList(userId);
        if (tagList == null || tagList.size() == 0) {
            return queryPage(page,new DynamicParams(),userId);
        }
        EntityWrapper<Dynamic> entityWrapper = new EntityWrapper<>();
        setVisibility(entityWrapper, userId);
        entityWrapper.eq("dc.user_id",userId).ne("d.state", 0);
        StringBuilder orStr = new StringBuilder();
        tagList.forEach(tag -> {
            tag.replaceAll("'", "");
            orStr.append("title like '%").append(tag).append("%' ").append(" or ");
            orStr.append("tags like '%").append(tag).append("%' ").append(" or ");
        });

        String str = null;
        if (orStr.length() > 0) {
            str = orStr.substring(0, orStr.length() - 4);
        }
        entityWrapper.andNew(str);
        entityWrapper.orderBy("d.id", false);
        page.setOptimizeCount(true);
        List<DynamicVo> resultList = dynamicMapper.queryPage(page, entityWrapper,userId);
        setDetails(resultList, false);
        PageUtils pageUtils = new PageUtils(resultList, page.getTotal());
        return pageUtils;
    }

    @Override
    public PageUtils queryPageByUserLike(Page<Dynamic> page, Integer userId) {
        EntityWrapper<Dynamic> entityWrapper = new EntityWrapper<>();
        setVisibility(entityWrapper, userId);
        entityWrapper.ne("d.state", 0).eq("dl.user_id", userId).orderBy("d.id", false);
        page.setOptimizeCount(true);
        List<DynamicVo> resultList = dynamicMapper.queryPageByUserLike(page, entityWrapper,userId);
        setDetails(resultList, false);
        PageUtils pageUtils = new PageUtils(resultList, page.getTotal());
        return pageUtils;
    }

    @Override
    public PageUtils queryPageByUserCollection(Page<Dynamic> page, Integer userId) {
        EntityWrapper<Dynamic> entityWrapper = new EntityWrapper<>();
        setVisibility(entityWrapper, userId);
        entityWrapper.ne("d.state", 0).eq("dc.user_id", userId).orderBy("d.id", false);
        page.setOptimizeCount(true);
        List<DynamicVo> resultList = dynamicMapper.queryPageByUserCollection(page, entityWrapper,userId);
        setDetails(resultList, false);
        PageUtils pageUtils = new PageUtils(resultList, page.getTotal());
        return pageUtils;
    }

    @Override
    public PageUtils queryPage(Page<Dynamic> page, DynamicParams dynamicParams, Integer userId) {

        EntityWrapper<Dynamic> entityWrapper = new EntityWrapper<>();
        //状态
        entityWrapper.ne("d.state", 0);
        setVisibility(entityWrapper, userId);

        if (dynamicParams.getType() != null) {
            entityWrapper.eq("d.type", dynamicParams.getType());
        }
        if (StrKit.isNotEmpty(dynamicParams.getProvinceCode())) {
            entityWrapper.eq("d.province_code", dynamicParams.getProvinceCode());
        }
        if (StrKit.isNotEmpty(dynamicParams.getCityCode())) {
            entityWrapper.eq("d.city_code", dynamicParams.getCityCode());
        }
        //行业
        if (StrKit.isNotEmpty(dynamicParams.getParentCategoryCode())) {
            entityWrapper.eq("d.parent_category_code ", dynamicParams.getParentCategoryCode());
        }
        if (StrKit.isNotEmpty(dynamicParams.getSubCategoryCode())) {
            entityWrapper.eq(" d.sub_category_code", dynamicParams.getSubCategoryCode());
        }
        //属性搜索
        if (dynamicParams.getAttributeFilter() != null && dynamicParams.getAttributeFilter().size() > 0) {
            dynamicParams.getAttributeFilter().forEach(stringObjectMap -> {
                Object attributeId = stringObjectMap.get("attributeId");
                if (attributeId == null) {
                    return;
                }
                Object value = stringObjectMap.get("value");
                Object code = stringObjectMap.get("code");
                if (value != null && code == null) {
                    entityWrapper.exists("SELECT 1 from dynamic_attribute da where da.dynamic_id = d.id and da.attribute_id = " + attributeId + " and da.value = '" + value + "' ");
                } else if (code != null) {
                    entityWrapper.exists("SELECT 1 from dynamic_attribute da where da.dynamic_id = d.id and da.attribute_id = " + attributeId + " and da.code = '" + code + "' ");
                }
            });
        }
        //模糊搜索标签
        if (StrKit.isNotEmpty(dynamicParams.getLikeStr())) {
            entityWrapper.and("d.tags like {0} or d.title like {0}","%" +  dynamicParams.getLikeStr() + "%" );
        }
        //排序
        if (StrKit.isNotEmpty(dynamicParams.getSortField())) {
            boolean sortType;
            if (dynamicParams.getSortType() == null || dynamicParams.getSortType() == 1) {
                sortType = false;
            } else {
                sortType = true;
            }
            entityWrapper.orderBy("d.like_quantity", sortType).orderBy("d.comment_quantity", sortType);
        } else {
            //默认创建时间 倒序
            entityWrapper.orderBy("d.id", false);
        }
        page.setOptimizeCount(true);
        List<DynamicVo> resultList = dynamicMapper.queryPage(page, entityWrapper,userId);
        setDetails(resultList, false);
        PageUtils pageUtils = new PageUtils(resultList, page.getTotal());
        return pageUtils;
    }

    @Override
    public List<DynamicVo> getRecommendList(Integer userId) {
        String key = null;
        UserDetailsDto userDetailsDto = null;

        if (userId != null) {
            userDetailsDto = userService.getUserName(userId);
            key = String.format(RedisKeyConstant.DYNAMIC_RECOMMEND_LIST, userId);
        }else{
            key = String.format(RedisKeyConstant.DYNAMIC_RECOMMEND_LIST, "All");
        }
        if (RedisUtil.hasKey(key)) {
            return RedisUtil.getArray(key, DynamicVo.class);
        }
        EntityWrapper<Dynamic> entityWrapper = new EntityWrapper<>();
        if (userDetailsDto != null && StrKit.isNotEmpty(userDetailsDto.getParentCategoryCode())) {
            entityWrapper.eq("d.parent_category_code", userDetailsDto.getParentCategoryCode());
        }
        if (userDetailsDto != null && userDetailsDto.getType() != null && userDetailsDto.getType() == 1) {
            entityWrapper.in("d.visibility", "1, 4");
        } else {
            entityWrapper.eq("d.visibility", 1);
        }
        //状态
        entityWrapper.ne("d.state", 0);
        entityWrapper.orderBy("d.like_quantity", false).orderBy("d.comment_quantity", false);
        Page<Dynamic> page = new Page();
        page.setSearchCount(false);
        page.setSize(20);//
        List<DynamicVo> result = dynamicMapper.queryRecommendPage(page, entityWrapper,userId);
        RedisUtil.setValue(key, result, ExpiresTimeEnum.LEVEL_4.getExpiresTime());
        return result;
    }


}